<?php
$host = '0.0.0.0';
$port = 8081;
$listen_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($listen_socket, $host, $port);
socket_set_option($listen_socket, SOL_SOCKET, SO_REUSEPORT, 1);
socket_listen($listen_socket);

echo " Tcp server on {$host}:{$port}" . PHP_EOL;
socket_set_nonblock($listen_socket);
$conn_arr = [];
$event_arr = [];

$eventBase = new EventBase();

$event = new Event($eventBase, $listen_socket, Event::READ | Event::PERSIST,
    function ($listen_socket) {
        global $eventBase, $conn_arr, $event_arr;
        if (($connect_socket = socket_accept($listen_socket)) != false) {
            echo "new connect " . intval($connect_socket) . PHP_EOL;
            socket_set_nonblock($connect_socket);
            broadcast($connect_socket, $conn_arr, intval($connect_socket) . " come!" . PHP_EOL);

            $conn_arr[intval($connect_socket)] = $connect_socket;

            $event = new Event($eventBase, $connect_socket, Event::READ | Event::PERSIST,
                function ($connect_socket) {
                    global $conn_arr;
                    $buffer = socket_read($connect_socket, 65535);
                    broadcast($connect_socket, $conn_arr, $buffer);
                }, $connect_socket);

            $event->add();
            // 此处值得注意，我们需要将事件本身存储到全局数组中，如果不保存，连接会话会丢失，也就是说服务端和客户端将无法保持持久会话
            $event_arr[intval($connect_socket)] = $event;

        }
    }, $listen_socket);
$event->add();
$eventBase->loop();

function broadcast($from_conn, $conn_arr, $msg)
{
    foreach ($conn_arr as $conn_item) {
        if ($from_conn != $conn_item) {
            $msg = intval($from_conn) . ' say:' . $msg;
            socket_write($conn_item, $msg, strlen($msg));
        }
    }
}








































